﻿// 修改自 https://github.com/zmjack/Chinese/blob/master/Chinese/ChineseNumber.cs

using System.Text;
using System.Text.RegularExpressions;

namespace PBIW.Operating
{
    public sealed class NumberInChineseProvider
    {
        public NumberInChineseProvider() { }

        private static readonly string[] figures = new[] { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        private static readonly string[] smallLevels = new[] { "", "十", "百", "千" };
        private static readonly string[] bigLevels = new[] { "", "万", "亿", "兆", "京", "垓", "秭", "穰" };

        private static IEnumerable<(int index, T value)> WithIndex<T>(
            IEnumerable<T> enumerable, int starting)
        {
            foreach (var item in enumerable)
            {
                yield return (starting, item);
                starting++;
            }
        }

        private string GetStringOfOneLevel(string singles, int bigLevelIndex)
        {
            if (singles.Length == 0)
                return string.Empty;

            var sb = new StringBuilder();
            var frontIsZero = false;

            foreach (var (index, single) in WithIndex(singles, 1))
            {
                if (single is '0')
                    frontIsZero = true;
                else
                {
                    var value = figures[single - '0'];
                    var singleNumberUnit = smallLevels[singles.Length - index];

                    if (frontIsZero)
                        _ = sb.Append($"{figures[0]}{value}{singleNumberUnit}");
                    else
                        _ = sb.Append($"{value}{singleNumberUnit}");

                    frontIsZero = false;
                }
            }

            if (sb.Length is 0)
                return figures[0];
            else
                return sb.Append(bigLevels[bigLevelIndex]).ToString();
        }

        private IEnumerable<(string str, int level)> CutLevelFromEnd(string str)
        {
            int level = 0;
            for (bool notEnded = true; notEnded; level++)
            {
                int ending = str.Length - level * 4;
                int starting = ending - 4;
                if (starting <= 0)
                {
                    notEnded = false;
                    starting = 0;
                }
                yield return (str[starting..ending], level);
            }
        }

        public string GetString(int value)
        {
            var stringValue = Math.Abs(value).ToString();

            var resultEnumrable = this.CutLevelFromEnd(stringValue)
                .Reverse().Select((s) => this.GetStringOfOneLevel(s.str, s.level));
            var resultString = string.Join("", resultEnumrable);

            resultString = Regex.Replace(resultString, $"{figures[0]}{{2,}}", figures[0]);
            if (resultString.StartsWith("一十"))
                resultString = resultString[1..];
            if (value < 0)
                resultString = $"负{resultString}";
            return resultString;
        }
    }
}
